package Multithreads;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import MonteCarlo.MonteCarlo;
 
public class MyCallable implements Callable<Double> {
 
	private String callPutFlag;
	private double s;
	private double x;
	private double t;
	private double r;
	private double b;
	private double v;
	private int nSteps;
	private int nSimulations;
	private int nbThreads;
	private int nbMonteCarlo;
	private double res;
	
	public MyCallable(){
		this.algo();
	}
	
	public MyCallable(String cPF, double dS, double dX, double dT, double dR, double dB, double dV, int nSt, int nSi, int nbT, int nbAlgo){
		callPutFlag = cPF;
		s = dS;
		x = dX;
		t = dT;
		r = dR;
		b = dB;
		v = dV;
		nSteps = nSt;
		nSimulations = nSi;
		nbThreads = nbT;
		nbMonteCarlo = nbAlgo;
		this.algo();
	}
	
    @Override
    public Double call() throws Exception {
        return res;
    }
     
    public void algo(){
		ExecutorService executor = Executors.newFixedThreadPool(nbMonteCarlo);
        List<Future<Double>> list = new ArrayList<Future<Double>>();
        for (int i = 0; i < nbMonteCarlo; i++) {
          Callable<Double> worker = new MonteCarlo(callPutFlag, s, x, t, r, b,	v, nSteps, nSimulations, nbThreads);
          Future<Double> submit = executor.submit(worker);
          list.add(submit);
        }
        System.out.println("Nombre de simulations de l'algorithme MonteCarlo = " + nbMonteCarlo);
        // now retrieve the result
        for (Future<Double> future : list) {
		  try {
		    res = future.get();
		  } catch (InterruptedException e) {
		    e.printStackTrace();
		  } catch (ExecutionException e) {
		    e.printStackTrace();
		  }
        }
        executor.shutdown();
    }

	public double getRes() {
		res = Math.round(res * Math.pow(10,6)) / Math.pow(10,6);
		return res;
	}
}